package com.glsc.ngateway.common.api.common.config;

import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.form.ContentType;
import feign.form.FormEncoder;
import feign.form.MultipartFormContentProcessor;
import feign.form.spring.SpringManyMultipartFilesWriter;
import feign.form.spring.SpringSingleMultipartFileWriter;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Type;
import java.util.*;

/**
 * @author 张宁
 * @version v1.0
 * @Description 重写Feign的编码格式
 * @date 2020 /12/04 14:16
 */
public class FeignSpringFormEncoder extends FormEncoder {


    public FeignSpringFormEncoder() {
        //this(new Default());

        this(((Encoder) (new Default())));
    }


    public FeignSpringFormEncoder(Encoder delegate) {
        super(delegate);
        MultipartFormContentProcessor processor = (MultipartFormContentProcessor) this.getContentProcessor(ContentType.MULTIPART);
        processor.addFirstWriter(new SpringManyMultipartFilesWriter());//优先使用多文件上传，解决PojoWriter的isApplicable函数判断是否适用时，适用的PojoUtil.isUserPojo(PojoUtil.java:50)判断导致.NullPointerException at feign.form.util.PojoUtil.isUserPojo(PojoUtil.java:50)
        processor.addFirstWriter(new SpringSingleMultipartFileWriter());
//        PojoWriter test;

    }


    /**
     * @param object
     * @param bodyType
     * @param template
     * @throws EncodeException
     * @Description 进行文件流的切割，为了实现多附件上传
     */
    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {

        //修改为下面的代码
        if (bodyType.equals(MultipartFile.class)) {
            MultipartFile file = (MultipartFile) object;
            Map<String, Object> data = Collections.singletonMap(file.getName(), object);
            super.encode(data, Encoder.MAP_STRING_WILDCARD, template);
            return;
        } else if (bodyType.equals(MultipartFile[].class)) {
            MultipartFile[] file = (MultipartFile[]) object;
            if (file != null) {
                Map<String, Object> data = Collections.singletonMap(file.length == 0 ? "" : file[0].getName(), object);
                super.encode(data, Encoder.MAP_STRING_WILDCARD, template);
                Map<String, Collection<String>> headers = template.headers();
                Collection<String> strings = headers.get("Content-Type");
                Collection<String> a = new ArrayList<>();
                strings.stream().forEach(x -> {
                    if (x.startsWith("multipart/form-data; charset=UTF-8; boundary=")) {
                        a.add(x);
                    }
                });
                Map<String, Collection<String>> res = new TreeMap<>();
                template.headers(res);
                res.put("Content-Length", headers.get("Content-Length"));
                res.put("Content-Type", a);
                template.headers(res);
                return;
            }
        }
        super.encode(object, bodyType, template);
    }


}